#pragma once

#include "mod.h"

namespace sfc::trait {

#if !__has_builtin(__is_trivially_destructible)
#define __is_trivially_destructible __has_trivial_destructor
#endif

template <class T>
struct Type {};

template <class T>
concept Enum = __is_enum(T);

template <class T>
concept Class = __is_class(T);

template <class T>
concept UInt = __is_same(T, unsigned char) || __is_same(T, unsigned short)
               || __is_same(T, unsigned int) || __is_same(T, unsigned long)
               || __is_same(T, unsigned long long);

template <class T>
concept SInt = __is_same(T, signed char) || __is_same(T, signed short) || __is_same(T, signed int)
               || __is_same(T, signed long) || __is_same(T, signed long long);

template <class T>
concept Int = UInt<T> || SInt<T>;

template <class T>
concept Float = __is_same(T, float) || __is_same(T, double) || __is_same(T, long double);

template <class... T>
concept Copy = (bool)(__is_constructible(T, const T&) && ...);

template <class... T>
concept TvCopy = (bool)(__is_trivially_copyable(T) && ...);

template <class... T>
concept TvDrop = (bool)(__is_trivially_destructible(T) && ...);

}  // namespace sfc::trait
